package cn.backflow.scheduling.service;

import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.utils.Key;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

@Service
public class JobService {

    private final String groupName = "normal-group";

    private final Scheduler scheduler;

    @Autowired
    public JobService(SchedulerFactoryBean schedulerFactory) {
        this.scheduler = schedulerFactory.getScheduler();
    }

    public void scheduleJob(Class<? extends Job> jobClass, String cronExpression) {
    }

    public String scheduleJob(Class<? extends Job> jobClass) throws SchedulerException {
        String id = UUID.randomUUID().toString();

        JobDetail job = newJob(jobClass)
                .withIdentity(id, groupName)
                // http://www.quartz-scheduler.org/documentation/quartz-2.2.x/configuration/ConfigJDBCJobStoreClustering.html
                // https://stackoverflow.com/a/19270566/285571
                .requestRecovery(true)
                .build();

        Trigger trigger = newTrigger()
                .withIdentity(id + "-trigger", groupName)
                .withSchedule(simpleSchedule().withIntervalInSeconds(30))
                .startNow()
                .build();

        scheduler.scheduleJob(job, trigger);

        return id;
    }

    public boolean deleteJob(String id) throws SchedulerException {
        JobKey jobKey = new JobKey(id, groupName);
        return scheduler.deleteJob(jobKey);
    }

    public List<String> jobs() throws SchedulerException {
        return scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))
                .stream()
                .map(Key::getName)
                .sorted(Comparator.naturalOrder())
                .collect(Collectors.toList());
    }

    public Map<String, Object> jobStatus() throws SchedulerException {
        Map<String, Object> status = new HashMap<>();


        for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {

            JobDetail jobDetail = scheduler.getJobDetail(jobKey);

            List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobDetail.getKey());

            for (Trigger trigger : triggers) {

                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());

                status.put(jobKey.getName(), triggerState);
            }
        }
        return status;
    }
}